package cutpart

import (
	"fmt"
	"strings"
	"time"

	"jihe.common/protos/base_server/proto"
	"jihe.common/tool"
)

func (s *Tx) BatchCreate(req *proto.BaseCutparts) (err error) {
	sqlStr := fmt.Sprintf("INSERT INTO %s (id, code, straight_line_idx, gap_idx, fabric_ids, obj_url,fashion_id)VALUES($1,$2,$3,$4,$5,$6,$7)", s.Name)
	stmt, err := s.Db.Prepare(sqlStr)
	if err != nil {
		return
	}
	defer stmt.Close()
	for _, v := range req.BaseCutpartList {
		id := fmt.Sprintf("%d", tool.GetSnowflakeId())
		_, err = s.Db.Exec(sqlStr, id, v.Code, v.StraightLineIdx, v.GapIdx, v.FabricIds, v.ObjUrl, req.FashionId)
		if err != nil {
			return
		}
	}
	return
}

func (s *Tx) DeleteByFashionId(fashionId string) (err error) {
	sqlStr := fmt.Sprintf("DELETE FROM %s WHERE fashion_id = $1", s.Name)
	_, err = s.Db.Exec(sqlStr, fashionId)
	if err != nil {
		return
	}
	return
}

func (s *Model) DeleteById(id string) (err error) {
	sqlStr := fmt.Sprintf("DELETE FROM %s WHERE id = $1", s.Name)
	_, err = s.Db.Exec(sqlStr, id)
	if err != nil {
		return
	}
	return
}

func (s *Tx) DeleteByIds(ids []string) (err error) {
	sqlStr := fmt.Sprintf("DELETE FROM %s WHERE id = $1", s.Name)
	stmt, err := s.Db.Prepare(sqlStr)
	if err != nil {
		return
	}
	defer stmt.Close()
	for _, id := range ids {
		_, err = stmt.Exec(id)
		if err != nil {
			return
		}
	}
	return
}

func (s *Model) UpdateFabricIds(req *proto.BaseUpdateCutpartFabricReq) (err error) {
	sqlStr := fmt.Sprintf("UPDATE %s SET fabric_ids = $1 WHERE id = $2", s.Name)
	stmt, err := s.Db.Prepare(sqlStr)
	if err != nil {
		return
	}
	defer stmt.Close()
	for _, cutpartId := range req.CutpartIds {
		_, err = s.Db.Exec(sqlStr, req.FabricIds, cutpartId)
		if err != nil {
			return
		}
	}
	return
}

func (s *Model) UpdateById(req *proto.BaseCutpart) (err error) {
	sqlStr := fmt.Sprintf("UPDATE %s SET algorithm_method = $1, straight_line_idx = $2, gap_idx = $3, fabric_ids = $4, updated_at = $5 WHERE id = $6", s.Name)
	_, err = s.Db.Exec(sqlStr, req.AlgorithmMethod, req.StraightLineIdx, req.GapIdx, req.FabricIds, time.Now().Format("2006-01-02 15:04:05"), req.Id)
	if err != nil {
		return
	}
	return
}

func (s *Model) ExistByfabric(fabricId string) (exist bool) {
	sqlStr := fmt.Sprintf("SELECT COUNT(0) FROM %s WHERE fabric_ids ILIKE $1", s.Name)
	count := 0
	err := s.Db.QueryRow(sqlStr, fabricId+"%").Scan(&count)
	if err != nil {
		return
	}
	if count != 0 {
		exist = true
	}
	return
}

func (s *Model) GetById(id string) (ret *proto.BaseCutpart, err error) {
	ret = new(proto.BaseCutpart)
	sqlStr := fmt.Sprintf("SELECT id, code, algorithm_method, straight_line_idx, gap_idx, fabric_ids, fashion_id, obj_url, created_at, updated_at FROM %s WHERE id = $1", s.Name)
	var (
		createdAt *time.Time
		updatedAt *time.Time
	)
	err = s.Db.QueryRow(sqlStr, id).Scan(&ret.Id, &ret.Code, &ret.AlgorithmMethod, &ret.StraightLineIdx, &ret.GapIdx, &ret.FabricIds, &ret.FashionId, &ret.ObjUrl, &createdAt, &updatedAt)
	if err != nil {
		return
	}
	if createdAt != nil {
		ret.CreatedAt = createdAt.Format("2006-01-02 15:04:05")
	}
	if updatedAt != nil {
		ret.UpdatedAt = updatedAt.Format("2006-01-02 15:04:05")
	}
	return
}

func (s *Model) GetByIds(ids []string) (ret []*proto.BaseCutpart, err error) {
	args := make([]string, len(ids))
	vals := make([]interface{}, len(ids))
	for k, v := range ids {
		args[k] = fmt.Sprintf("$%d", k+1)
		vals[k] = v
	}
	sqlStr := fmt.Sprintf("SELECT id, code, algorithm_method, straight_line_idx, gap_idx, fabric_ids, fashion_id, obj_url, created_at, updated_at FROM %s WHERE id in ("+strings.Join(args, ",")+")", s.Name)
	rows, err := s.Db.Query(sqlStr, vals...)
	if err != nil {
		return
	}
	defer rows.Close()
	for rows.Next() {
		var (
			createdAt *time.Time
			updatedAt *time.Time
		)
		item := &proto.BaseCutpart{}
		err = rows.Scan(&item.Id, &item.Code, &item.AlgorithmMethod, &item.StraightLineIdx, &item.GapIdx, &item.FabricIds, &item.FashionId, &item.ObjUrl, &createdAt, &updatedAt)
		if err != nil {
			return
		}
		if createdAt != nil {
			item.CreatedAt = createdAt.Format("2006-01-02 15:04:05")
		}
		if updatedAt != nil {
			item.UpdatedAt = updatedAt.Format("2006-01-02 15:04:05")
		}
		ret = append(ret, item)
	}
	return
}

func (s *Model) GetListByFashionId(fashionId string) (ret []*proto.BaseCutpart, err error) {
	sqlStr := fmt.Sprintf("SELECT id, code, algorithm_method, straight_line_idx, gap_idx, fabric_ids, fashion_id, obj_url, created_at, updated_at FROM %s WHERE fashion_id = $1 ORDER BY id", s.Name)
	rows, err := s.Db.Query(sqlStr, fashionId)
	if err != nil {
		return
	}
	for rows.Next() {
		item := &proto.BaseCutpart{}
		var (
			createdAt *time.Time
			updatedAt *time.Time
		)
		rows.Scan(&item.Id, &item.Code, &item.AlgorithmMethod, &item.StraightLineIdx, &item.GapIdx, &item.FabricIds, &item.FashionId, &item.ObjUrl, &createdAt, &updatedAt)
		if createdAt != nil {
			item.CreatedAt = createdAt.Format("2006-01-02 15:04:05")
		}
		if updatedAt != nil {
			item.UpdatedAt = updatedAt.Format("2006-01-02 15:04:05")
		}
		ret = append(ret, item)
	}
	return
}
